using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Smled.States;

namespace Smled
{
    public partial class MainForm : Form
    {
        static MainForm instance = null;
        string cFileName = "";
        ResizeDialog resDiag;
        TileSetEditor tsEd;
        int selX = 0, selY = 0;

        public MainForm()
        {
            InitializeComponent();
            resDiag = new ResizeDialog();
            tsEd = new TileSetEditor();

            //mapView1.Map.Set = new TileSet("C:\\mario.mts");
            tileChooser.Set = mapView1.Map.Set;
            
            mapView1.Chooser = tileChooser;
            mapView1.SelectionChange += new EventHandler<SelectionChangeEventArgs>(mapView1_SelectionChange);
            mapView1.MapChange += new EventHandler(mapView1_MapChange);
            instance = this;

            initStates();
        }

        public BaseState brushState = null,
                            managedBrushState = null,
                            randomBrushState = null,
                            selectState = null;

        private void initStates()
        {
            brushState = new BrushState(mapView1);
            managedBrushState = new ManagedBrushState(mapView1);
            randomBrushState = new RandomBrushState(mapView1);
            selectState = new SelectState(mapView1);
        }

        public static MainForm Instance
        {
            get
            {
                if (instance == null) instance = new MainForm();
                return instance;
            }
        }

        void mapView1_MapChange(object sender, EventArgs e)
        {
            tsMapSize.Text = "Map size : " + mapView1.Map.Width.ToString() + " x " + mapView1.Map.Height.ToString();
        }

        void mapView1_SelectionChange(object sender, SelectionChangeEventArgs e)
        {
            tsCursorPosition.Text = "Cursor position : " + e.posX.ToString() + ", " + e.posY.ToString();
            selX = e.posX;
            selY = e.posY;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TileSetEditor tse = new TileSetEditor();
            tse.Show();

        }

        private void tsBackColor_Click(object sender, EventArgs e)
        {
            if (colorDialog.ShowDialog() != DialogResult.Cancel)
            {
                mapView1.BackColor = colorDialog.Color;
            }
        }

        private void tsUndo_Click(object sender, EventArgs e)
        {
            mapView1.DoUndo();
        }

        private void tsRedo_Click(object sender, EventArgs e)
        {
            mapView1.DoRedo();
        }

        Size ParseDimString(string dim)
        {
            if (dim.Length < 3) throw new Exception("String too short!");

            string[] par = dim.Split(new string[] {";"}, 20, StringSplitOptions.RemoveEmptyEntries);
            if (par.Length != 2) throw new Exception("String too short!");

            Size s = new Size(0, 0);
            try
            {
                s.Width = Int32.Parse(par[0]);
                s.Height = Int32.Parse(par[1]);
            }
            catch (Exception)
            {
                throw new Exception("String too short!");
            }

            if (s.Width > 0 && s.Height > 0 && s.Width <= 500 && s.Height <= 500)
            {
                return s;
            }
            else
            {
                throw new Exception("String too short!");
            }
        }

        private void newSizeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("Click!");
            if (!TryToSave()) return;

            Size s;
            try
            {
                s = ParseDimString(txtNewSize.Text);
                TileSet ts = mapView1.Map.Set;
                mapView1.Map = new TileMap(s.Width, s.Height);
                mapView1.Map.Set = ts;
            }
            catch (Exception)
            {
                MessageBox.Show("Illegal dimension string! Range (1 - 500), correct format : width;height" + Environment.NewLine + "Example : 20;30", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            
        }

        private bool Save()
        {
            //MessageBox.Show("Not implemented.", "Error", MessageBoxButtons.OK);
            if (mapSaveDialog.ShowDialog() == DialogResult.Cancel) return false;
            if (!mapView1.Map.SaveToFile(mapSaveDialog.FileName))
            {
                MessageBox.Show("Saving failed!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            cFileName = mapSaveDialog.FileName;
            return true;
        }

        private bool TryToSave()
        {
            if (mapView1.IsChanged)
            {
                DialogResult dr = MessageBox.Show("Do you want to save the current map?", "Map changed", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
                if (dr == DialogResult.Cancel) return false;
                if (dr == DialogResult.No) return true;

                if (!Save()) return false;
            }

            return true;
        }

        private void sameSizeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!TryToSave()) return;
            //TileMap tm = new TileMap(mapView1.Map.Width, mapView1.Height);
            //mapView1.BackColor = Color.Blue;
            mapView1.Map = new TileMap(mapView1.Map.Width, mapView1.Map.Height);
            mapView1.Map.Set = tileChooser.Set;
            mapView1.ClearUndo();
        }

        private void copyToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(mapView1.Map.GetArrayString(), TextDataFormat.Text);
        }

        private void saveAsFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void openAFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (mapOpenDialog.ShowDialog() == DialogResult.Cancel) return;

            if (!mapView1.LoadMap(mapOpenDialog.FileName))
            {
                MessageBox.Show("Error loading file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                cFileName = mapOpenDialog.FileName;
                tileChooser.Set = mapView1.Map.Set;
                tileChooser.Refresh();
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (cFileName.Length == 0 || !System.IO.File.Exists(cFileName))
            {
                Save();
            }
            else
            {
                mapView1.Map.SaveToFile(cFileName);
            }
        }

        private void tsResize_Click(object sender, EventArgs e)
        {
            resDiag.MapWidth = mapView1.Map.Width;
            resDiag.MapHeight = mapView1.Map.Height;

            if (resDiag.ShowDialog() == DialogResult.Cancel) return;

            if (resDiag.MapWidth < mapView1.Map.Width || resDiag.MapHeight < mapView1.Map.Height)
            {
                if (MessageBox.Show("Are you sure you want to resize the map from " +
                    mapView1.Map.Width.ToString() + " x " + mapView1.Map.Height.ToString() + " to " +
                    resDiag.MapWidth.ToString() + " x " + resDiag.MapHeight + "? This action will cause cropping.",
                    "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
                {
                    return;
                }
            }

            mapView1.ResizeMap(resDiag.MapWidth, resDiag.MapHeight, resDiag.CropAlignment);
        }

        private void reloadLastToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (cFileName == null || cFileName.Length == 0)
            {
                openAFileToolStripMenuItem_Click(this, new EventArgs());
            }
            else
            {
                if (!mapView1.LoadMap(cFileName))
                {
                    MessageBox.Show("Error loading file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void tsTileSet_Click(object sender, EventArgs e)
        {
            tsEd.CurrentSet = mapView1.Map.Set;
            //tsEd.ref
            if (tsEd.ShowDialog() == DialogResult.Cancel) return;

            mapView1.Map.Set = tsEd.CurrentSet;
            tileChooser.Set = tsEd.CurrentSet;
            tileChooser.Invalidate();
            mapView1.Invalidate();
        }

        private void copyToClipboardSBToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(mapView1.Map.GetArrayStringBBall(selX, selY), TextDataFormat.Text);
        }

        public MapView MainView
        {
            get
            {
                return mapView1;
            }
        }

        private void tbBrush_Click(object sender, EventArgs e)
        {
            mapView1.State = brushState;
        }

        private void toolBox_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void tbManagedBrush_Click(object sender, EventArgs e)
        {
            mapView1.State = managedBrushState;
        }

        public void activateState(BaseState s)
        {
            toolStripContainer1.TopToolStripPanel.Controls.Clear();

            if (s.ToolBar != null)
            {
                toolStripContainer1.TopToolStripPanel.Controls.Add(s.ToolBar);
                toolStripContainer1.TopToolStripPanelVisible = true;
                toolStripContainer1.TopToolStripPanel.Invalidate();
            }
            else
            {
                toolStripContainer1.TopToolStripPanelVisible = false;
            }
        }

        private void tbBrush_Click_1(object sender, EventArgs e)
        {
            mapView1.State = brushState;
        }

        private void tbRandomBrush_Click(object sender, EventArgs e)
        {
            mapView1.State = randomBrushState;
        }

        private void tbSelect_Click(object sender, EventArgs e)
        {
            mapView1.State = selectState;
        }
    }
}